package com.demo.minicat;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 *
 * 启动类
 * @author: lipan
 * @date: 2021/9/27 19:30
 */

public class Bootstrap {

    //端口为8080
    private int port = 8080;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }


    private Map<String, HttpServlet> servletMap = new HashMap<String, HttpServlet>();

    // 定义一个线程池
    int corePoolSize = 10;
    int maximumPoolSize =50;
    long keepAliveTime = 100L;
    TimeUnit unit = TimeUnit.SECONDS;
    BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
    ThreadFactory threadFactory = Executors.defaultThreadFactory();
    RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();


    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            corePoolSize,
            maximumPoolSize,
            keepAliveTime,
            unit,
            workQueue,
            threadFactory,
            handler
    );


    private void loadServlet() {
        try {
            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("web.xml");
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(inputStream);
            Element rootElement = document.getRootElement();
            List<Element> list = rootElement.selectNodes("//servlet");
            for (Element element : list) {
                Element servletNameNode = (Element) element.selectSingleNode("servlet-name");
                Element servletClassNode = (Element) element.selectSingleNode("servlet-class");

                String servletName = servletNameNode.getStringValue().trim();
                String ServletClassName = servletClassNode.getStringValue().trim();

                Element mappingNode = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                Element urlNode = (Element) mappingNode.selectSingleNode("url-pattern");
                servletMap.put(urlNode.getStringValue().trim(), (HttpServlet) Class.forName(ServletClassName).getDeclaredConstructor().newInstance());

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }


    public void start() throws Exception {

        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("server start on:" + port);

        //启动加载servlet
        loadServlet();

        //v1.0 返回固定字符串到浏览器
//        while (true){
//            Socket accept = serverSocket.accept();
//            InputStream inputStream = accept.getInputStream();
//            int times=0;
//            while (inputStream.read()==0){
//                inputStream.read();
//                times++;
//            }
//            System.out.println("循环了:"+times+"次");
//            //读到数据再往下走
//            String header = HttpUtils.getHeader(HttpStatus.OK);
//            accept.getOutputStream().write((header+"MiniCat!").getBytes());
//            inputStream.close();
//            accept.close();
//        }


        //访问静态资源 v2.0
//        while (true){
//            Socket accept = null;
//            Response response=null;
//            InputStream inputStream=null;
//
//            //catch是为了不因为客户端异常请求 而导致服务端停止运行
//            try {
//                accept = serverSocket.accept();
//                inputStream = accept.getInputStream();
//                Request request = new Request(inputStream);
//                response=new Response(accept.getOutputStream());
//                response.outputResource(request.getUri());
//            } catch (FileNotFoundException e) {
//                response.outPut(HttpUtils.getHeader(HttpStatus.NOTFOUND));
//            }catch (Exception e){
//                e.printStackTrace();
//            }
//            finally {
//                inputStream.close();
//                accept.close();
//            }
//        }


        //3.0 支持静态资源 与动态资源访问

//        while (true) {
//            Socket accept = null;
//            Response response = null;
//            InputStream inputStream = null;
//            try {
//                accept = serverSocket.accept();
//                inputStream = accept.getInputStream();
//                Request request = new Request(inputStream);
//                response = new Response(accept.getOutputStream());
//                //动态资源
//                String uri = "/" + request.getUri();
//                if (servletMap.containsKey(uri)) {
//                    HttpServlet httpServlet = servletMap.get(uri);
//                    httpServlet.service(request, response);
//                } else {
//                    response.outputResource(request.getUri());
//                }
//            } catch (FileNotFoundException e) {
//                response.outPut(HttpUtils.getHeader(HttpStatus.NOTFOUND));
//            } catch (Exception e) {
//                e.printStackTrace();
//            } finally {
//                inputStream.close();
//                accept.close();
//            }
//        }


        //多线程
        while (true){
            //这个是线程从队列中取连接请求 可以使用多线程 也可以不使用多线程
            Socket accept = serverSocket.accept();
            RequestProcessor processor=new RequestProcessor(accept,servletMap);
//            processor.start();
            threadPoolExecutor.execute(processor);
        }


}



    public static void main(String[] args)  throws Exception{

        Bootstrap bootstrap=new Bootstrap();
        bootstrap.start();
    }


}
